package com.gitee.hermer.engine.jars.app.sdk;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import com.gitee.hermer.boot.jee.commons.collection.CollectionUtils;
import com.gitee.hermer.boot.jee.commons.log.UtilsContext;
import com.gitee.hermer.boot.jee.commons.reflect.ClassUtils;
import com.gitee.hermer.boot.jee.commons.utils.StringUtils;
import com.gitee.hermer.engine.jars.core.annotate.EngineComponent;
import com.gitee.hermer.engine.jars.core.annotate.EngineAppJob;
import com.gitee.hermer.engine.jars.core.app.domain.EngineAppJobContext;
import com.gitee.hermer.engine.jars.core.app.domain.EngineAppJobMethodBean;

public class EngineApplicationRefreshBeanEvent extends UtilsContext implements ApplicationListener<ContextRefreshedEvent>{

	@Autowired(required = false) 
	private EngineAppJobContext context;

	private List<String> exclusionMethods = CollectionUtils.newArrayList("wait","equals","toString","hashCode","getClass","notify","notifyAll");


	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		if(event.getApplicationContext().getClassLoader() instanceof EngineAppClassLoader){
			EngineAppClassLoader appClassLoader = (EngineAppClassLoader) event.getApplicationContext().getClassLoader();
			
			Map<String, Object> beans = event.getApplicationContext().getBeansWithAnnotation(EngineComponent.class);
			for (String beanName : beans.keySet()) {
				Object bean = beans.get(beanName);
				try{
					Class clazz = ClassUtils.getTargetProxy(bean).getClass();
					Method[] methods = clazz.getMethods();
					for (Method method : methods) {
						if(method == null || exclusionMethods.contains(method.getName()))
							continue;
						if(context != null){
							EngineAppJob job = method.getAnnotation(EngineAppJob.class);
							if(job != null && StringUtils.isNotBlank(job.jobMethod())){
								context.registerJob(job.jobMethod(), new EngineAppJobMethodBean(appClassLoader.getCacheKey(),
										clazz,job,beanName,method.getName(),job.version(),job.describe(),
										method,method.getGenericParameterTypes(),method.getParameterTypes(),method.getReturnType()));
							}

						}

					}
				}catch (Exception e) {
					// TODO: handle exception
				}
			}
		}
	}

}
